/*
* ============================================================================
*  Name        : sea_assert.h
*  Part of     : Finite state machine utilities
*  Description : Assert directives
*  Version     : %version: %
*  
*
* ============================================================================
*/
/**
 * @file sea_assert.h
 *
 * @ingroup Platforms
 */

#if !defined( __sea_assert_h__ )
#define __sea_assert_h__

#include "sea_platform.h"
#include "sea_trace.h"

namespace sea
{
    /**
     * @def SEA_BREAKPOINT
     * @brief Platform specific breakpoint
     * @ingroup Platforms
     */
    #if defined( SEA_OS_SOS )
        #define SEA_BREAKPOINT( )    __BREAKPOINT( )
    #else

        #if ( defined (__i386__) || defined ( __x86_64__ ) ) && defined ( __GNUC__ ) && __GNUC__ >= 2

            #define SEA_BREAKPOINT( )    __asm__ __volatile__ ( "int $03" )

        #elif ( defined ( _MSC_VER ) || defined ( __DMC__ ) ) && defined ( _M_IX86 )

            #define SEA_BREAKPOINT( )  { __asm int 3h }

        #elif defined ( __alpha__ ) && !defined( __osf__ ) && defined ( __GNUC__ ) && __GNUC__ >= 2

            #define SEA_BREAKPOINT( )  __asm__ __volatile__ ( "bpt" )

        #else
            #define SEA_BREAKPOINT( )  assert( 0 )
        #endif
    #endif

    /**
     * @def ASSERT_ALWAYS
     * @brief Asserts always
     * @ingroup Platforms
     */
    #define ASSERT_ALWAYS( x )  \
        if ( !( x ) ) \
        { \
            SEA_TRACE( "*** ASSERT Line %d File %s\nExpression: %s", __LINE__, __FILE__, #x ); \
            SEA_BREAKPOINT( ); \
        }

    #if defined( DEBUG )

        /**
         * @def ASSERT_ALWAYS
         * @brief Asserts in debug mode only 
         * @ingroup Platforms
         */
        #define ASSERT_DEBUG( x )   ASSERT_ALWAYS( x )

    #else

        /**
         * @def ASSERT_ALWAYS
         * @brief Asserts in debug mode only 
         * @ingroup Platforms
         */
        #define ASSERT_DEBUG( x )

    #endif

}
#endif
